/**
 * Project Name:九色鹿
 * File Name:DynamicSecurityMetadataSource.java
 * Package Name:com.fxp.project.jiuselu.security.component
 * Date:2021年03月14日 15:22
 * Copyright (c) 2021, Jason.Wang All Rights Reserved.
 */
package com.fxp.project.jiuselu.security.component;

import com.fxp.project.jiuselu.security.service.DynamicSecurityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * ClassName:DynamicSecurityMetadataSource<br/>
 * Function: 动态权限加载器<br/>
 * Date:2021年03月14日 15:22<br/>
 *
 * @author Jason.Wang
 * @version 1.0.0.0
 * @see
 * @since JDK1.8
 */
public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private DynamicSecurityService dynamicSecurityService;
    /**
     * 权限的配置器
     */
    private static Map<String, ConfigAttribute> configAttributeMap = null;

    /**
     * loadDataSource: 从数据库里面加载数据，可以结合Redis<br/>
     *
     * @author Jason.Wang
     * @createTime 2021/3/14 15:27
     */
    @PostConstruct
    public void loadDataSource() {
        configAttributeMap = dynamicSecurityService.loadDataSource();
    }

    /**
     * clearDataSource: 清理权限数据<br/>
     *
     * @author Jason.Wang
     * @createTime 2021/3/14 15:27
     */
    public void clearDataSource() {
        configAttributeMap.clear();
        configAttributeMap = null;
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        //如果当前的权限缓存不存在，那么就从数据库等地方加载
        if (configAttributeMap == null) {
            this.loadDataSource();
        }
        List<ConfigAttribute> configAttributes = new ArrayList<>();
        //获取当前访问的路径
//        String url = ((FilterInvocation) o).getRequestUrl();
//        String path = URLUtil.getPath(url);
        /**
         * @FIXED 明显用系统自带的功能就可以解决的，为什么要用第三方工具？
         */
        String url = ((FilterInvocation) o).getRequest().getServletPath();
        PathMatcher pathMatcher = new AntPathMatcher();
        Iterator<String> iterator = configAttributeMap.keySet().iterator();
        //获取访问该路径所需资源
        while (iterator.hasNext()) {
            String pattern = iterator.next();
            if (pathMatcher.match(pattern, url)) {
                configAttributes.add(configAttributeMap.get(pattern));
            }
        }
        // 未设置操作请求权限，返回空集合
        return configAttributes;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
